#include "message.hpp"
#include <map>



using namespace std;

static map<MsgKind, string> g_presetErrorInfoMap = 
{
    { MsgKind::Ok, ""},
    { MsgKind::Unknown, "unknown error"},
    { MsgKind::FileNotExist, "file is not exist"},
    { MsgKind::DirNotExist, "directory is not exist"},
    { MsgKind::InvalidOperation, "invalid operation"},
    { MsgKind::ImcompleteIo, "input/output or receive/send imcomplete"},
    { MsgKind::ExternalLibError, "calling external library and return an error"},
    { MsgKind::OsRelatedError, "this is an operating system-related error"},
    { MsgKind::IncorrectChecksum, "checksum is incorrect" },
    { MsgKind::InvalidData, "invalid data" },
    { MsgKind::InitFailed, "init failed" },
    { MsgKind::ExecuteFailed, "execute failed" },
    { MsgKind::Timeout, "timeout" },
    { MsgKind::Busy, "busy" },
    { MsgKind::InvalidArgument, "invalid argument" },
    { MsgKind::OpenFailed, "open failed" },
    { MsgKind::Receiving, "receiving" },
    { MsgKind::NotPassiveMode, "not passive mode" },
    { MsgKind::InvalidMessageReceiver, "invalid message receiver" },
    { MsgKind::ZhUnknown, "未知错误"},
    { MsgKind::ZhFileNotExist, "文件不存在"},
    { MsgKind::ZhDirNotExist, "路径不存在"},
    { MsgKind::ZhInvalidOperation, "无效操作"},
    { MsgKind::ZhImcompleteIo, "输入或输出不完整"},
    { MsgKind::ZhExternalLibError, "外部输入错误"},
    { MsgKind::ZhOsRelatedError, "这是一个与操作系统相关的错误"},
    { MsgKind::ZhIncorrectChecksum, "校验不正确" },
    { MsgKind::ZhInvalidData, "无效的数据" },
    { MsgKind::ZhInitFailed, "初始化失败" },
    { MsgKind::ZhExecuteFailed, "执行失败" },
    { MsgKind::ZhTimeout, "超时" },
    { MsgKind::ZhBusy, "正在忙" },
    { MsgKind::ZhInvalidArgument, "无效的参数" },
    { MsgKind::ZhOpenFailed, "打开失败" },
    { MsgKind::ZhReceiving, "接收中..." },
    { MsgKind::ZhSent, "发送中..." },
    { MsgKind::ZhInvalidMessageReceiver, "无效的消息接收者" },
    { MsgKind::ZhInitializing, "初始化中..." },
    { MsgKind::ZhTaskStart, "任务开始" },
    { MsgKind::ZhRunning, "运行中..." },
    { MsgKind::ZhAbort, "任务中止" },
    { MsgKind::ZhDetecting, "检测中..." },
    { MsgKind::ZhDoNotOperate, "请勿操作" },
    { MsgKind::ZhCompleted, "已完成" },
    { MsgKind::ZhExceed, "已超出" },
    { MsgKind::ZhReset, "正在复位..." },
};

Message Message::create(MsgKind kind, const string &customizedInfo)noexcept 
{
    auto ins = Message();
    ins.m_kind = kind;
    if (true == customizedInfo.empty()) 
    {
        ins.m_message = g_presetErrorInfoMap[kind];
    }
    else 
    {
        ins.m_message = customizedInfo;
    }

    return ins;
}

Message::Message(MsgKind kind) 
{
    m_kind = kind;
    // m_message = 0 != g_presetErrorInfoMap.count(kind) ? g_presetErrorInfoMap[kind] : "";
}

Message::Message(const Message &another)noexcept 
{
    m_kind = another.m_kind;
    m_message = another.m_message;
}

Message::Message(Message &&another)noexcept 
{
    m_kind = another.m_kind;
    m_message = std::move(another.m_message);
}

Message &Message::operator=(const Message &rhs)noexcept 
{
    m_kind = rhs.m_kind;
    m_message = rhs.m_message;

    return *this;
}

Message &Message::operator=(Message &&rhs)noexcept 
{
    m_kind = rhs.m_kind;
    m_message = std::move(rhs.m_message);

    return *this;
}

bool Message::operator==(const Message &rhs)const noexcept 
{
    return m_kind == rhs.m_kind && m_message == rhs.m_message;
}

bool Message::operator!=(const Message &rhs)const noexcept 
{
    return !(rhs == *this);
}

bool Message::isOk()const noexcept 
{
    return MsgKind::Ok == m_kind;
}

Message::operator int()const noexcept 
{
    return this->code();
}

Message::operator string()const noexcept 
{
    return this->toString();
}

string Message::toString()const noexcept 
{
    if (true == this->isOk())
    {
        return m_message;
    }

    return m_message + ", msg code: " + to_string(this->code());
}

void Message::appendInfo(const string &info) noexcept 
{
    if (true == this->isOk()) 
    {
        return;
    }

    m_message += ", ";
    m_message += info;
}

int Message::code()const noexcept 
{
     return static_cast<int>(m_kind);
}

const string &Message::message()const noexcept 
{
    return m_message;
}